namespace GemBox.Spreadsheet
{
    using System;
    using System.Collections;
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Xml;

    internal class SpreadsheetRelationshipCollection : ICollection, IEnumerable
    {
        private Hashtable hashtable = new Hashtable();
        private ArrayList items = new ArrayList();
        private Random random = new Random();

        private void Add(SpreadsheetRelationship relationship)
        {
            this.hashtable[relationship.Rid] = this.items.Add(relationship);
        }

        public string Add(string type, string target, string targetMode)
        {
            string rid = null;
            int num = 0;
            while (num < 0x3e8)
            {
                rid = "GemRid" + this.random.Next(0x2710).ToString();
                if (this.hashtable[rid] == null)
                {
                    this.Add(new SpreadsheetRelationship(rid, type, target, targetMode));
                    break;
                }
                num++;
            }
            if (num == 0x3e8)
            {
                throw new SpreadsheetException("GemRid could not be assigned!");
            }
            return rid;
        }

        public void CopyTo(Array array, int i)
        {
            throw new NotImplementedException();
        }

        public IEnumerator GetEnumerator()
        {
            return this.items.GetEnumerator();
        }

        public string GetFirstVisibleOccurrencePath(string contentType)
        {
            foreach (SpreadsheetRelationship relationship in this)
            {
                if (relationship.IsVisible && (relationship.Type == contentType))
                {
                    return relationship.Target;
                }
            }
            return null;
        }

        public static string GetRelationshipPathFromXmlFilePath(string xmlFilePath)
        {
            return (Path.GetDirectoryName(xmlFilePath).Replace(@"\", "/") + "/_rels/" + Path.GetFileName(xmlFilePath) + ".rels");
        }

        public int GetTypeCount(string contentType)
        {
            int num = 0;
            foreach (SpreadsheetRelationship relationship in this)
            {
                if (relationship.Type == contentType)
                {
                    num++;
                }
            }
            return num;
        }

        public ArrayList GetVisiblePathsCollection(string contentType)
        {
            ArrayList list = new ArrayList();
            foreach (SpreadsheetRelationship relationship in this)
            {
                if (relationship.IsVisible && (relationship.Type == contentType))
                {
                    list.Add(relationship.Target);
                }
            }
            return list;
        }

        public void LoadRels(string partPath, PackageBuilderBase packageBuilder)
        {
            string relationshipPathFromXmlFilePath = GetRelationshipPathFromXmlFilePath(partPath);
            if (packageBuilder.Parts.ContainsKey(relationshipPathFromXmlFilePath))
            {
                XmlTextReader reader = new XmlTextReader(packageBuilder.GetPart(relationshipPathFromXmlFilePath));
                try
                {
                    while (Utilities.ReadToFollowing(reader, "Relationship"))
                    {
                        string reqAttrString = Utilities.GetReqAttrString(reader, "Id");
                        string target = Utilities.GetReqAttrString(reader, "Target");
                        string type = Utilities.GetReqAttrString(reader, "Type");
                        string attribute = reader.GetAttribute("TargetMode");
                        SpreadsheetRelationship relationship = new SpreadsheetRelationship(reqAttrString, type, target, attribute);
                        this.Add(relationship);
                    }
                }
                finally
                {
                    reader.Close();
                }
            }
        }

        public void Remove(string contentType)
        {
            foreach (SpreadsheetRelationship relationship in this)
            {
                if (relationship.Type == contentType)
                {
                    relationship.IsVisible = false;
                }
            }
        }

        public void SaveRels(string partPath, PackageBuilderBase packageBuilder)
        {
            string relationshipPathFromXmlFilePath = GetRelationshipPathFromXmlFilePath(partPath);
            XmlTextWriter writer = new XmlTextWriter(packageBuilder.CreatePart(relationshipPathFromXmlFilePath, "application/vnd.openxmlformats-package.relationships+xml"), new UTF8Encoding(false));
            try
            {
                writer.WriteStartDocument(true);
                writer.WriteStartElement("Relationships");
                writer.WriteAttributeString("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships");
                foreach (SpreadsheetRelationship relationship in this)
                {
                    if (relationship.IsVisible)
                    {
                        writer.WriteStartElement("Relationship");
                        writer.WriteAttributeString("Id", relationship.Rid);
                        writer.WriteAttributeString("Type", relationship.Type);
                        writer.WriteAttributeString("Target", relationship.Target);
                        if (relationship.TargetMode != null)
                        {
                            writer.WriteAttributeString("TargetMode", relationship.TargetMode);
                        }
                        writer.WriteEndElement();
                    }
                }
                writer.WriteEndElement();
            }
            finally
            {
                writer.Close();
            }
        }

        public int Count
        {
            get
            {
                return this.items.Count;
            }
        }

        public bool IsSynchronized
        {
            get
            {
                throw new NotImplementedException();
            }
        }

        public SpreadsheetRelationship this[string rid]
        {
            get
            {
                return (SpreadsheetRelationship) this.items[(int) this.hashtable[rid]];
            }
        }

        public object SyncRoot
        {
            get
            {
                throw new NotImplementedException();
            }
        }
    }
}
